package game.engine.base

import android.graphics.Canvas
import android.graphics.Matrix

class WindowAdapter(
    val minX: Float,
    val maxX: Float,
    val minY: Float,
    val maxY: Float,
    val scale: Float,
    val realWidth: Float,
    val realHeight: Float,
    val devWidth: Float,
    val devHeight: Float,
)

object Fps{
    var elapsed = 0f
    var frameCount = 0
    var fps = 0
}

class Director(val gameApp: IGameApp, val renderView: RenderView) {

    companion object {
        lateinit var instance: Director
    }

    init {
        instance = this
    }

    val screenMatrix = Matrix()

    //-------------------------------
    // properties
    var devWidth = 720f
    var devHeight = 1280f

    //
    var paused = true

    var firstFrame = false

    var inited = false
    var mLastTimeMs = System.currentTimeMillis()
    lateinit var windowAdapter: WindowAdapter
    lateinit var graphics: Graphics

    //
    var curScene: Scene? = null
    var nextScene: Scene? = null

    fun initDirector() {
        if (CoreDebug.DirectorDebug) {
            CoreDebug.info("initDirector called!")
        }
        // 计算 windowAdapter信息
        val scale = renderView.realWidth / devWidth
        val maxY = renderView.realHeight / scale / 2f
        val minY = -maxY
        val maxX = devWidth / 2f
        val minX = -maxX
        windowAdapter = WindowAdapter(
            minX = minX,
            maxX = maxX,
            minY = minY,
            maxY = maxY,
            scale = scale,
            realWidth = renderView.realWidth,
            realHeight = renderView.realHeight,
            devWidth = devWidth,
            devHeight = devHeight
        )
        graphics = Graphics()


        screenMatrix.setTranslate(windowAdapter.realWidth / 2f, windowAdapter.realHeight / 2f)
        screenMatrix.preScale(windowAdapter.scale, windowAdapter.scale)

        //---------------------------------
        // 提供一些个回调?
        gameApp.launchGame()
        curScene?.onEnter()
    }

    fun mainLoop(canvas: Canvas) {

        if (!inited) {
            // 判断是否可以 init
            if (renderView.isReady) {
                initDirector()
                inited = true
            }
            return
        }

        // surfaceview 销毁重新创建的时候,可能导致 dt 很大
        if (firstFrame) {
            mLastTimeMs = System.currentTimeMillis()
            firstFrame = false
        }

        var cur = System.currentTimeMillis()
        var spendMs = cur - mLastTimeMs
        mLastTimeMs = cur
        val dt = spendMs / 1000f
        updateAndDraw(dt, canvas)

        // 计算fps
        if (CoreDebug.FpsDebug){
            Fps.elapsed += dt
            Fps.frameCount++
            if (Fps.elapsed >= 1f){
                Fps.elapsed -= 1f
                Fps.fps = Fps.frameCount
                Fps.frameCount = 0
            }
        }
    }

    private fun updateAndDraw(dt: Float, canvas: Canvas) {

        if (paused) return

        if (dt > 0.2f && CoreDebug.DirectorDebug) {
            CoreDebug.warn("dt:${dt} 为什么会这么的大呢?")
        }

        curScene?.frameUpdate(dt,canvas)
        if (curScene?.willDestroy == true){
            curScene = nextScene
            curScene?.onEnter()
            nextScene = null
        }
    }

    //--------------------------
    // 场景切换和管理
    fun startScene(scene: Scene) {
        if (CoreDebug.DirectorDebug) {
            CoreDebug.info("director startScene called")
            if (curScene != null) {
                CoreDebug.warn("curScene is not null! 请使用 replaceScene.")
                return
            }
        }

        curScene = scene
    }

    fun replaceScene(scene: Scene) {
        curScene?.onExit()
        nextScene = scene
    }

    fun pause() {
        if (!paused) {
            paused = true
            if (CoreDebug.DirectorDebug) {
                CoreDebug.info("director pause!")
            }
        }
    }

    fun resume() {
        if (paused) {
            paused = false
            if (CoreDebug.DirectorDebug) {
                CoreDebug.info("director resume!")
            }
        }
    }

    fun stopEngine() {
        if (CoreDebug.DirectorDebug){
            CoreDebug.info("stopEngine called!")
        }
        pause()
        curScene?.onExit()
        graphics.release()
    }

    //---------------------------
    // TODO : 后面分离出去
    fun addTouch(touch: Touch) {
        if (curScene != null){
            curScene!!.inputMgr.addTouch(touch)
        }
    }
}